package com.lcf.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.utils.UserUtils;
import com.lcf.framework.vo.PageVO;
import com.lcf.system.dao.SysTenantUserDao;
import com.lcf.system.dto.user.TenantAddUserDTO;
import com.lcf.system.entity.SysTenant;
import com.lcf.system.entity.SysTenantUser;
import com.lcf.system.entity.SysUser;
import com.lcf.system.manager.CacheManager;
import com.lcf.system.manager.SysTenantManager;
import com.lcf.system.query.user.SysTenantUserPageQuery;
import com.lcf.system.service.SysTenantUserService;
import com.lcf.system.vo.tenant.SysTenantVO;
import com.lcf.system.vo.tenantUser.SysTenantUserPageVO;
import com.lcf.system.vo.tenantUser.SysTenantUserVO;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;

/**
 * 租户-用户(SysTenantUser)表服务实现类
 *
 * @author lcf
 * @since 2025-03-02 23:00:39
 */
@Service("sysTenantUserService")
public class SysTenantUserServiceImpl extends ServiceImpl<SysTenantUserDao, SysTenantUser> implements SysTenantUserService {
    @Resource
    private SysTenantManager sysTenantManager;
    @Resource
    private CacheManager cacheManager;

    @Override
    public void add(TenantAddUserDTO dto) {
        String keyword = dto.getKeyword();
        SysUser sysUser = Db.lambdaQuery(SysUser.class)
                .and(x -> x.eq(SysUser::getUsername, keyword)
                        .or().eq(StringUtils.isNotBlank(keyword), SysUser::getMobile, keyword)
                )
                .one();

        if (sysUser == null) {
            throw new SysException("用户不存在!");
        }

        boolean exists = Db.lambdaQuery(SysTenantUser.class)
                .eq(SysTenantUser::getTenantId, UserUtils.getTenantId())
                .eq(SysTenantUser::getUserId, sysUser.getId())
                .exists();
        if (exists) {
            throw new SysException("用户已加入租户");
        }

        new SysTenantUser(UserUtils.getTenantId(), sysUser.getId()).insert();
    }

    @Override
    public void quit() {
        long userId = UserUtils.getUserId();
        sysTenantManager.quit(UserUtils.getTenantId(), userId);

        //删除用户缓存
        cacheManager.delUserCache(userId);
    }

    @Override
    public void kickOut(long userId) {
        sysTenantManager.quit(UserUtils.getTenantId(), userId);

        //删除用户缓存
        cacheManager.delUserCache(userId);
    }

    @Override
    public PageVO<SysTenantUserPageVO> page(SysTenantUserPageQuery query) {
        Page<SysTenantUser> page = Db.lambdaQuery(SysTenantUser.class)
                .eq(SysTenantUser::getTenantId, UserUtils.getTenantId())
                .eq(query.getUserId() != null, SysTenantUser::getUserId, query.getUserId())
                .page(query.toPage());

        return new PageVO<>(page, SysTenantUserPageVO.class);
    }

    @Override
    public SysTenantUserVO getDetail(long userId) {
        SysUser sysUser = Db.lambdaQuery(SysUser.class).eq(SysUser::getId, userId).one();
        if (sysUser == null) {
            throw new SysException("用户不存在");
        }

        return BeanUtil.copyProperties(sysUser, SysTenantUserVO.class);
    }

    @Override
    public List<SysTenantVO> userTenantList(long userId) {
        List<Long> tenantIdList = Db.lambdaQuery(SysTenantUser.class)
                .eq(SysTenantUser::getUserId, userId)
                .list()
                .stream().map(SysTenantUser::getTenantId)
                .toList();

        if (CollectionUtils.isEmpty(tenantIdList)) {
            return Collections.emptyList();
        }

        return Db.lambdaQuery(SysTenant.class)
                .in(SysTenant::getId, tenantIdList)
                .list()
                .stream()
                .map(x -> BeanUtil.copyProperties(x, SysTenantVO.class))
                .toList();
    }
}

